	;; d7.l has location for player 2 scoreboard
	;; either $40BA0003 or $47840003
PrepareLevelCommon:
	;; save d7 for later use
	move.l	d7,-(a7)
	bsr.s	PrepareLevelCommonPart1
	bra.s	PrepareLevelCommonPart2NoPush
	;; the PrepareLevelCommonPart2NoPush will have a rts
	
PrepareLevelCommonPart1:
	bsr	FadeOut
	
	;; reset time to wait for demo
	clr.w	VintWait
	;; clear words for level
	clr.b	WordsForLevel

	;; clear HScroll cell
	move.l	#$5C000003,d7
	bsr	ClearHScroll32

	;; clear plane A VRAM C000
	move.l  #$40000003,d7
	bsr     ClearPlane64By28In64By32
	;; clear plane B VRAM E000
	move.l  #$60000003,d7
	bsr     ClearPlane64By28In64By32

	rts

	;; d7.l has location for player 2 scoreboard
PrepareLevelCommonPart2:	
	move.l	d7,-(a7)
PrepareLevelCommonPart2NoPush:	
	
	;; copy score and word display (player 1)
	;; make high priority (so score will go above other things)
	lea     StartScoreWord(pc),a5
	move.w  #$8000,d4
        moveq   #(StartRowScoreWord-StartScoreWord-1),d5
        moveq   #(((EndScoreWord-StartScoreWord)/(StartRowScoreWord-StartScoreWord))-1),d6
	;; VRAM C084
	move.l	#$40840003,d7
	bsr     CopyMapAAndMakeBorderB

	;; update score (same d4 color)
        move.l  #$40900003,d0
	move.w  #(EndScoreAscii-StartScoreAscii-1),d1
	lea     StartScoreAscii,a5
	bsr	DisplayScore

	;; restore d7, saving in d0 for score update
	move.l	(a7)+,d7
	move.l	d7,d0

	;; if two player, update score and word box
	btst	#TwoPlayerFlag,Flags
	beq.s	PrepareLevelCommonSkipTwoPlayer

	;; copy score and word display (player 1)
	;; make high priority (so score will go above other things)
	lea     StartScoreWord(pc),a5
	move.w  #$A000,d4
        moveq   #(StartRowScoreWord-StartScoreWord-1),d5
        moveq   #(((EndScoreWord-StartScoreWord)/(StartRowScoreWord-StartScoreWord))-1),d6
	bsr     CopyMapAAndMakeBorderB

	;; update score (same d4 color)
	;; d0 was not modified by CopyMapAAndMakeBorderB, so have address of
	;; score message box location, need to offset by 12 for score number
	addi.l	#$000C0000,d0
	move.w  #(EndScoreAscii2-StartScoreAscii2-1),d1
	lea     StartScoreAscii2,a5
	bsr	DisplayScore
PrepareLevelCommonSkipTwoPlayer:	

	bsr.s	PickNewWord

	rts

	
PickNewWord:
	;; save registers
	movem.l  d0-d1/a5-a6,-(a7)
	;; clear both WordIndex and WordIndex2
	clr.w	WordIndex
	lea	StartWordLetters,a5
	;; get a random number in d0
	bsr	NextRandom
	;; have 128 words in our list, so pick one of them
	andi.w	#$007f,d0
	;; 3 letter words, so multiply our word index by 3 to get byte offset
	mulu.w  #$0003,d0
	;; copy three bytes over
	lea	StartWord3List(pc),a6
	;; copy three character for word over
	move.b  (a6,d0.w),(a5)+
	move.b  1(a6,d0.w),(a5)+
	move.b  2(a6,d0.w),(a5)+
	;; null terminate string
	move.b  #$00,(a5)+
	;; randomize locations
	move.w	#(EndWordY-StartWordX-1),d1
	lea	StartWordX,a5
PickNewWordRandomizeLocationsLoop:
	bsr	NextRandom
	move.b	d0,(a5)+
	dbf	d1,PickNewWordRandomizeLocationsLoop
	;; restore registers
	movem.l  (a7)+,d0-d1/a5-a6
	rts

	
	;; refresh the tile each letter sprite uses
RefreshLetters:	
	movem.w d0-d1,-(a7)
	lea	StartWordLetters,a5
	;; update letter tile used (note $00 and $20 are clear tiles)
	clr.w	d0
	cmpi.b  #$20,LetterSprite+5
	beq.s   RefreshLettersSkipLetterUpdate
	move.b	WordIndex,d0
	move.b  (a5,d0.w),d1
	move.b  d1,LetterSprite+5
RefreshLettersSkipLetterUpdate:
	cmpi.b  #$20,Letter2Sprite+5
	beq.s   RefreshLettersSkipLetter2Update
	move.b	WordIndex2,d0
	move.b  (a5,d0.w),d1
	move.b  d1,Letter2Sprite+5
RefreshLettersSkipLetter2Update:
	movem.w (a7)+,d0-d1
	rts


	;; a5 WordIndex address
	;; d0.w has word index
	;; d1.w has word index for other player
GetNextLetter:	
	;; clear several flags
	andi.b	#($FF^((1<<FinishedWordFlag)|(1<<NewWordFlag)|(1<<NewLevelFlag))),WordFlags
	bset	#RefreshLettersWordFlag,WordFlags
	addq.b  #1,d0
	lea	StartWordLetters,a6
	move.b  (a6,d0),d2
	;; if character is not null, still have more letters in word
	tst.b   d2
	bne.s   GetNextLetterDone
	;; current player finished word
	bset	#FinishedWordFlag,WordFlags
	;; check if all players finished their word
	btst	#TwoPlayerFlag,Flags
	beq.s	GetNextLetterOnNewWord
	;; if 2 player, then check if other player is also at end of word
	cmp.w	d0,d1
	bne.s	GetNextLetterDone
GetNextLetterOnNewWord:	
	;; ready for a new word
	addq.b	#1,WordsForLevel
	cmpi.b	#LevelWords,WordsForLevel
	bge.s	GetNextLetterOnNewLevel
	;; pick a new word if all players are ready for a new word
	bset	#NewWordFlag,WordFlags
	bsr	PickNewWord
	clr.b   d0
	;; reset both players to first character of new word
	clr.b	WordIndex
	clr.b	WordIndex2
	clr.b	LetterSprite+5
	clr.b	Letter2Sprite+5
	bra.s	GetNextLetterDone
GetNextLetterOnNewLevel:
	bset	#NewLevelFlag,WordFlags
GetNextLetterDone:
	rts

	
	;; a5 has address of score
	;; d0.l has vdp address
	;; d1.w has length-1
	;; d4.w has upper byte for tile
	;; d4.b	is overwritten
DisplayScore:
	movem.w	d1,-(a7)
	move.l	d0,(a4)
DisplayScoreLoop:	
        move.b  (a5)+,d4
        move.w  d4,(a3)
        dbf     d1,DisplayScoreLoop
	movem.w	(a7)+,d1
	rts

	;; a5 has end address of score
	;; d0.l has vdp address
	;; d1.w has length-1
	;; d2.w has word index
	;; d4.w has upper byte for tile
	;; d4.b	is overwritten
UpdateAndDisplayScoreAndWord:
	movem.w	d3,-(a7)
        move.w  d1,d3
	move.b  #1,d4
UpdateScoreLoop:
	add.b   d4,-(a5)
	;; $30-$39 are valid ASCII numbers, above this and we want to carry
	cmpi.b  #$3A,(a5)
	bge.s   UpdateScoreKeepIncrementing
	clr.b   d4
	dbf	d3,UpdateScoreLoop
	bra.s   ReadyForDisplayScore
UpdateScoreKeepIncrementing:	
	move.b  #$30,(a5)
	dbf	d3,UpdateScoreLoop
ReadyForDisplayScore:	
	;; display score using another available subroutine for this
	bsr.s	DisplayScore
	;; display picked up letters
	addi.l	#$00800000,d0
	move.l	d0,(a4)
	lea	StartWordLetters,a5
	move.w	d2,d3
DisplayWordLoop:	
        move.b  (a5)+,d4
        move.w  d4,(a3)
        dbf    d3,DisplayWordLoop

	;; check if only showing first letter
	tst.b	d2
	bne.s	UpdateAndDisplayScoreAndWordDone
	;; put in underscores to clear old word
	;; don't need d1 after this
	subq.w	#1,d1
	;; want to keep same palette
	move.b	#$5f,d4
DisplayWordUnderscoresLoop:	
        move.w   d4,(a3)
	dbf	d1,DisplayWordUnderscoresLoop
UpdateAndDisplayScoreAndWordDone:	
	movem.w	(a7)+,d3
	rts


	;; wait for a certain time or a start button press before
	;; transitioning to another level
LevelTransition:
	;; reset vint wait
	clr.w	VintWait
LevelTransitionLoop:
	bsr	WaitForVint
	cmpi.w	#VintWaitLevelTransition,VintWait
	bge.s	LevelTransitionDone
	btst	#bitStart,Port1Press
	bne.s	LevelTransitionDone
	btst	#TwoPlayerFlag,Flags
	beq.s	LevelTransitionSkipPort2
	btst	#bitStart,Port2Press
	bne.s	LevelTransitionDone
LevelTransitionSkipPort2:	
	bra.s	LevelTransitionLoop
LevelTransitionDone:	
	rts

	;; this actually common to title and level0
TitleTruckAnimateMove:
	;; title, animate slow d0, d1 move slow, animate slow XXXX
	movem.w	 d0-d2,-(a7)
	move.b	 #$0F,d0
	move.w	 #1,d1
	;; get truck x position
	move.w	 TruckLeftSprite+6,d2
	;; check for wrap around
	cmpi.w 	 #(520),d2
	blt.s    TruckAnimateMoveCommon
	;; found wrap around, switch palettes between green/blue trucks
	bchg	 #5,TruckLeftSprite+4
	bchg	 #5,TruckRightSprite+4
	;; move the truck to the left side
	subi.w	 #500,d2
	bra.s	 TruckAnimateMoveCommon

Level0TruckAnimateMove:
	;; game, animate fast d0, d1 move fast, animate fast
	movem.w	 d0-d2,-(a7)
	btst	 #TwoPlayerFlag,Flags
	bne.s	 DoneTruckAnimateMove
	move.b	 #$07,d0
	move.w	 #2,d1
	;; get truck x position
	move.w	 TruckLeftSprite+6,d2
	;; game truck stops once off screen
	cmpi.w	 #(80+320+56),d2
	bgt.s	 DoneTruckAnimateMove

TruckAnimateMoveCommon:
	;; add speed to truck x position
	add.w	 d1,d2
	move.w	 d2,TruckLeftSprite+6
	addi.w	 #32,d2
	move.w	 d2,TruckRightSprite+6
	;; animate truck tires
	bsr.s    TruckTireSpin
DoneTruckAnimateMove:
	movem.w	(a7)+,d0-d2
	rts

	;; animate truck tires if timer on boundary of d0
	;; destroys d0.b
TruckTireSpin:	
        and.b    VintCounter+1,d0
        bne.s    DoneTruckTireSpin
	;; save a5
	movem.l	a5,-(a7)
	;; animate each truck
	lea	TruckLeftSprite,a5
	bsr.s	TruckTireSpinAnimate
	lea	Truck2LeftSprite,a5
	bsr.s	TruckTireSpinAnimate
	;; restore a5
	movem.l	(a7)+,a5
DoneTruckTireSpin:	
	rts

	;; (a5) has TruckLeftSprite/Truck2LeftSprite
	;; animate truck 1 tires
TruckTireSpinAnimate:	
	;; switch between two truck animation frames
	cmpi.b	 #$AD,5(a5)
	beq.s	 TruckTireSpinAnimateSecondFrame
	move.b	 #$AD,5(a5)
	move.b	 #$BD,13(a5)
	bra.s	 DoneTruckTireSpinAnimate
TruckTireSpinAnimateSecondFrame:	
	move.b	 #$C9,5(a5)
	move.b	 #$D9,13(a5)
DoneTruckTireSpinAnimate:	
	rts

	;; a5.l riley sprite
NextStrideFrame:	
        cmpi.b  #$8C,5(a5)
        blt.s   NextStrideFrameReset
        cmpi.b  #$98,5(a5)
        bge.s   NextStrideFrameReset
        addq.b  #6,5(a5)
        rts
NextStrideFrameReset:	
        move.b  #$8C,5(a5)
	rts
	